package com.soft.javase.ch09.test.collections;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wangzhisen
 * @Desc TODO
 * @date 2025/5/5
 *
 * 按照斗地主的规则，完成**洗牌发牌**的动作。
 * 具体规则：
 * 使用54张牌打乱顺序,三个玩家参与游戏，三人交替摸牌，每人17张牌，最后三张留作底牌。
 * 牌进行排序、拿大王的可以拿底牌。
 *
 * 1.做牌  Card 花色color、数字num、索引index  --》 存储至List<Card>
 * 2.乱序  --> Collections的shuffle()
 * 3.发牌  --> 51张牌 %3  + 剩余3张牌作为底牌  --》 存储至List<Card>
 * 4.底牌  --> 拿取大王的可以拿底牌
 * 5.排序  --> 将各玩家的牌进行排序
 *
 * "♠", "♥", "♣", "♦"
 * "2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3"
 */

public class LandlordsGame {
    // 定义花色和数字
    private static final String[] COLORS = {"♠", "♥", "♣", "♦"};
    private static final String[] NUMBERS = {"2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3"};

    public static void main(String[] args) {
        // 1. 做牌
        List<Card> cards = createCards();

        // 2. 乱序
        Collections.shuffle(cards);

        // 3. 发牌
        List<Card> bottomCards = new ArrayList<>(); // 底牌
        List<List<Card>> playersCards = new ArrayList<>(); // 三个玩家的牌

        for (int i = 0; i < 3; i++) {
            playersCards.add(new ArrayList<>());
        }

        // 发牌逻辑
        for (int i = 0; i < 51; i++) {
            playersCards.get(i % 3).add(cards.get(i));
        }

        // 剩余3张作为底牌
        bottomCards.addAll(cards.subList(51, 54));

        // 4. 确定谁可以拿底牌（谁有大王）
        int landlordIndex = -1;
        for (int i = 0; i < 3; i++) {
            if (hasBigJoker(playersCards.get(i))) {
                landlordIndex = i;
                break;
            }
        }

        // 如果没人有大王，随机指定一个玩家拿底牌
        if (landlordIndex == -1) {
            landlordIndex = new Random().nextInt(3);
        }

        // 拿底牌
        playersCards.get(landlordIndex).addAll(bottomCards);
        bottomCards.clear();

        // 5. 排序
        for (List<Card> playerCards : playersCards) {
            sortCards(playerCards);
        }

        // 输出结果
        System.out.println("========== 发牌结果 ==========");
        for (int i = 0; i < 3; i++) {
            System.out.println("玩家" + (i + 1) + (i == landlordIndex ? "(地主)" : "(农民)") + "的牌:");
            System.out.println(formatCards(playersCards.get(i)));
        }
        System.out.println("底牌: " + formatCards(bottomCards));
    }

    // 创建一副牌
    private static List<Card> createCards() {
        List<Card> cards = new ArrayList<>();
        int index = 0;

        // 添加普通牌
        for (String number : NUMBERS) {
            for (String color : COLORS) {
                cards.add(new Card(color, number, index++));
            }
        }

        // 添加大小王
        cards.add(new Card("", "小王", index++));
        cards.add(new Card("", "大王", index++));

        return cards;
    }

    // 检查是否有大王
    private static boolean hasBigJoker(List<Card> cards) {
        return cards.stream().anyMatch(card -> "大王".equals(card.getNumber()));
    }

    // 排序牌
    private static void sortCards(List<Card> cards) {
        cards.sort(Comparator.comparingInt(Card::getIndex));
    }

    // 格式化牌的输出
    private static String formatCards(List<Card> cards) {
        return cards.stream()
                .map(Card::toString)
                .collect(Collectors.joining(" "));
    }

    // 牌类
    static class Card {
        private String color;
        private String number;
        private int index; // 用于排序

        public Card(String color, String number, int index) {
            this.color = color;
            this.number = number;
            this.index = index;
        }

        public String getColor() {
            return color;
        }

        public String getNumber() {
            return number;
        }

        public int getIndex() {
            return index;
        }

        @Override
        public String toString() {
            return color + number;
        }
    }
}
